#include "cwidgetbrowser.h"
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))

#include <thread>
#include <QUrl>
#include <QRegExp>
#include <QTextCodec>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QWebChannel>
#include <QNetworkReply>
#include <QWebEngineHistory>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
#include <QWebEngineCookieStore>

#include "WebEngineView.h"

#if defined(QT_DEBUG)
    #include <QtDebug>
#endif

CWidgetBrowser::CWidgetBrowser(QWidget *parent /*= nullptr*/)
    : QWidget(parent)
{
    QWebEngineSettings *settings = QWebEngineSettings::globalSettings();
    settings->setAttribute(QWebEngineSettings::PluginsEnabled, true);  // 支持falsh插件
    settings->setAttribute(QWebEngineSettings::JavascriptEnabled, true);

    QWebEngineProfile *newProfile = new QWebEngineProfile("Default", this);
    newProfile->setCachePath(QWebEngineProfile::defaultProfile()->cachePath());
    newProfile->setHttpCacheType(QWebEngineProfile::defaultProfile()->httpCacheType());
    newProfile->setHttpUserAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) "
                                 "AppleWebKit/537.36 (KHTML, like Gecko) "
                                 "QupZilla/2.1.2 "
                                 "Chrome/49.0.2623.111 "
                                 "Safari/537.36");

    m_pWebView = new WebEngineView(this);
    connect(m_pWebView, &WebEngineView::loadStarted, this, &CWidgetBrowser::LoadStarted);
    connect(m_pWebView, &WebEngineView::loadFinished, this, &CWidgetBrowser::LoadFinished);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setMargin(0);
    layout->addWidget(m_pWebView);

    m_pPage = new QWebEnginePage(newProfile, m_pWebView);
    m_pWebView->setPage(m_pPage);

    connect(static_cast<WebEngineView *>(m_pWebView), &WebEngineView::EventTransit, this, &CWidgetBrowser::EventTransit);

    // 允许音视频捕获等权限，主要是webrtc使用
    connect(m_pWebView->page(), &QWebEnginePage::featurePermissionRequested, this, &CWidgetBrowser::slot_featurePermissionRequested);

    connect(m_pPage->profile(), &QWebEngineProfile::downloadRequested, this, &CWidgetBrowser::slot_downloadRequested);
}

CWidgetBrowser::~CWidgetBrowser()
{
    SetWindowObject(nullptr);
}

bool CWidgetBrowser::SetWindowObject(QObject *object)
{
    if (object == nullptr && m_pWindowObject != nullptr)
    {
        /// 取消register
        QWebChannel *webChannel = m_pPage->webChannel();
        if (webChannel != nullptr)
        {
            webChannel->deregisterObject(m_pWindowObject);
        }
        m_pWindowObject = nullptr;

        return true;
    }
    else if (object != nullptr && m_pWindowObject == nullptr)
    {
        /// register
        m_pWindowObject = object;
        QWebChannel *webChannel = new QWebChannel(m_pPage);
        webChannel->registerObject("window_external", m_pWindowObject);
        m_pPage->setWebChannel(webChannel);

        return true;
    }
    else
    {
        // 已经register
        return false;
    }
}

void CWidgetBrowser::InvokeScript(const QString &script)
{
    m_pPage->runJavaScript(script);
}

void CWidgetBrowser::InvokeScript(const QString &mothed, const QString &args)
{
    QString str = args;
    str.replace("\r\n", "");
    str.replace("\n", "");  // 去掉回车符号
    QString script = QString("%1(\'%2\');").arg(mothed).arg(str);
    return InvokeScript(script);
}

void CWidgetBrowser::LoadUrl(const QString &url)
{
    m_pWebView->load(QUrl(url));
}

void CWidgetBrowser::SetArrowToolMode(bool isArrowTool)
{
    static_cast<WebEngineView *>(m_pWebView)->SetArrowToolMode(isArrowTool);
}

void CWidgetBrowser::SetNoContextMenu()
{
    this->setContextMenuPolicy(Qt::NoContextMenu);
    m_pWebView->setContextMenuPolicy(Qt::NoContextMenu);
}

void CWidgetBrowser::SetBackgroundColor(const QColor &color)
{
    m_pPage->setBackgroundColor(color);
}

void CWidgetBrowser::Stop()
{
    m_pWebView->stop();
}

bool CWidgetBrowser::CanGoBack()
{
    QWebEngineHistory *history = m_pPage->history();
    return history->canGoBack();
}

void CWidgetBrowser::GoBack()
{
    m_pWebView->page()->triggerAction(QWebEnginePage::Back);
}

bool CWidgetBrowser::CanGoForward()
{
    QWebEngineHistory *history = m_pPage->history();
    return history->canGoForward();
}

void CWidgetBrowser::GoForward()
{
    m_pWebView->page()->triggerAction(QWebEnginePage::Forward);
}

void CWidgetBrowser::DeleteCookie()
{
    QWebEngineProfile *engineProfile = m_pWebView->page()->profile();
    QWebEngineCookieStore *cookie = engineProfile->cookieStore();
    cookie->deleteAllCookies(); //删除cookie
}

void CWidgetBrowser::Reload()
{
    m_pWebView->reload();
}

void CWidgetBrowser::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event)
    SetWindowObject(nullptr);
}

void CWidgetBrowser::slot_sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
{
#if defined(QT_DEBUG)
    for (QSslError e : errors)
    {
        qDebug() << "ssl error: " << e;
    }
#endif

    reply->ignoreSslErrors();
}


void CWidgetBrowser::slot_downloadRequested(QWebEngineDownloadItem *item)
{
    QString mimitype = item->mimeType();

    QStringList tmp = mimitype.split('/');

    QString filter("");
    if (tmp.size() >= 2)
    {
        filter = QString("%1(*.%2)").arg(tmp.at(0)).arg(tmp.at(1));
    }

    QString fileName = QFileDialog::getSaveFileName(this, ("Save File"), "./", filter);
    if (fileName.isEmpty())
    {
        return;
    }
    item->setPath(fileName);
    item->accept();
}

void CWidgetBrowser::slot_featurePermissionRequested(QUrl q, QWebEnginePage::Feature f)
{
    // 允许音视频捕获等权限，主要是webrtc使用
    m_pPage->setFeaturePermission(q, f, QWebEnginePage::PermissionGrantedByUser);
}

#endif
